//
//  AFHTTPSessionManager+MFAPMNetMonitor.m
//  MFAPMManager
//
//  Created by zhang liyu on 2019/7/12.
//

#import "AFHTTPSessionManager+MFAPMNetMonitor.h"

#import "NSObject+MFAPMSwizzle.h"
#import <pthread.h>

static NSMutableDictionary *mfapm_uploadBKDict;
static NSMutableDictionary *mfapm_downloadBKDict;
static pthread_mutex_t mfapm_uploadLock;
static pthread_mutex_t mfapm_downloadLock;

@implementation AFHTTPSessionManager (MFAPMNetMonitor)

#pragma mark - Swizzle Actions

+ (void)mfapm_swizzleRequestProgressActions{
    
    //初始化变量
    mfapm_uploadBKDict = [NSMutableDictionary dictionary];
    mfapm_downloadBKDict = [NSMutableDictionary dictionary];
    pthread_mutex_init(&mfapm_uploadLock, NULL);
    pthread_mutex_init(&mfapm_downloadLock, NULL);
    
    //交换方法
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [[self class] mfapm_swizzleInstanceSEL:@selector(GET:parameters:progress:success:failure:) toSEL:@selector(mfapm_GET:parameters:progress:success:failure:)];
        
        [[self class] mfapm_swizzleInstanceSEL:@selector(POST:parameters:progress:success:failure:) toSEL:@selector(mfapm_POST:parameters:progress:success:failure:)];
        
        [[self class] mfapm_swizzleInstanceSEL:@selector(POST:parameters:constructingBodyWithBlock:progress:success:failure:) toSEL:@selector(mfapm_POST:parameters:constructingBodyWithBlock:progress:success:failure:)];
        
    });
}

- (nullable NSURLSessionDataTask *)mfapm_GET:(NSString *)URLString
                                  parameters:(nullable id)parameters
                                    progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                                     success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                     failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure{
    
    [[self class] mfapm_setDownloadProgressBK:downloadProgress forKey:URLString];
    
    return [self mfapm_GET:URLString
                parameters:parameters
                  progress:downloadProgress
                   success:success
                   failure:failure];
}

- (nullable NSURLSessionDataTask *)mfapm_POST:(NSString *)URLString
                                   parameters:(nullable id)parameters
                                     progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                      success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                      failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure{
    
    [[self class] mfapm_setUploadProgressBK:uploadProgress forKey:URLString];
    
    return [self mfapm_POST:URLString
                 parameters:parameters
                   progress:uploadProgress
                    success:success
                    failure:failure];
}

- (nullable NSURLSessionDataTask *)mfapm_POST:(NSString *)URLString
                                   parameters:(nullable id)parameters
                    constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
                                     progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                      success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                      failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure{
    
    [[self class] mfapm_setUploadProgressBK:uploadProgress forKey:URLString];
    
    return [self mfapm_POST:URLString
                 parameters:parameters
  constructingBodyWithBlock:block
                   progress:uploadProgress
                    success:success
                    failure:failure];
}

#pragma mark - Progress Block Dictionary Actions

+ (nullable void (^)(NSProgress *))mfapm_uploadProgressBKForKey:(nullable NSString *)key{
    if(![key isKindOfClass:[NSString class]] || key.length == 0){
        return nil;
    }
    
    void (^uploadBK)(NSProgress *progress);
    
    pthread_mutex_lock(&mfapm_uploadLock);
    //保存数据
    uploadBK = [mfapm_uploadBKDict[key] copy];
    //获取数据后移除数据
    if(uploadBK){
        [mfapm_uploadBKDict removeObjectForKey:key];
    }
    pthread_mutex_unlock(&mfapm_uploadLock);
    
    return uploadBK;
}

+ (nullable void (^)(NSProgress *))mfapm_downloadProgressBKForKey:(nullable NSString *)key{
    if(![key isKindOfClass:[NSString class]] || key.length == 0){
        return nil;
    }
    
    void (^downloadBK)(NSProgress *progress);
    
    pthread_mutex_lock(&mfapm_downloadLock);
    //保存数据
    downloadBK = [mfapm_downloadBKDict[key] copy];
    //获取数据后移除数据
    if(downloadBK){
        [mfapm_downloadBKDict removeObjectForKey:key];
    }
    pthread_mutex_unlock(&mfapm_downloadLock);
    
    return downloadBK;
}

+ (void)mfapm_setUploadProgressBK:(void (^)(NSProgress *))bk forKey:(NSString *)key{
    if(!bk || ![key isKindOfClass:[NSString class]] || key.length == 0){
        return;
    }
    pthread_mutex_lock(&mfapm_uploadLock);
    
    [mfapm_uploadBKDict setObject:[bk copy] forKey:key];
    
    pthread_mutex_unlock(&mfapm_uploadLock);
}

+ (void)mfapm_setDownloadProgressBK:(void (^)(NSProgress *))bk forKey:(NSString *)key{
    if(!bk || ![key isKindOfClass:[NSString class]] || key.length == 0){
        return;
    }
    pthread_mutex_lock(&mfapm_downloadLock);
    
    [mfapm_downloadBKDict setObject:[bk copy] forKey:key];
    
    pthread_mutex_unlock(&mfapm_downloadLock);
}


@end
